﻿using System;
using System.Collections.Generic;
using Sustainalytics.Entities.ESGRatings;
using Sustainalytics.ESGRatings.Computing.Entities;

namespace Sustainalytics.ESGRatings.DataContract.ESG
{
    public class ComputeStatisticsOptions
    {
        public string ComputationContextDetails { get; set; }

        public bool ResetStatistics { get; set; }
    }


    /// <summary>
    /// Computation options that include filtering:
    /// by companies, comparative group type, company type, template type, comparative group lists
    /// and verbosity of response.
    /// Mandatory: MatrixId, ReferenceUniverseId
    /// </summary>
    public class ESGRatingsOptionsDto
    {
        public ESGRatingsOptionsDto()
        {
            GroupBy = ComparativeGroupEnum.PeerGroup;
            IncludeRatings = true;
            IncludeTopPerformersInfo = false;
            IncludeWeights = false;
            IncludeAggregatedScores = false;
            IncludeAggregatedWeights = false;
            TemplateType = TemplateTypeEnum.Combined;
            CompanyType = CompanyTypeEnum.Combined;
        }
        /// <summary>
        /// List of requested companies.
        /// Empty list means all.
        /// </summary>
        public List<Guid> CompaniesIds { get; set; }

        /// <summary>
        /// Filter for company's type, either public or private
        /// Default Combined
        /// </summary>
        public CompanyTypeEnum CompanyType { get; set; }

        /// <summary>
        /// Filter for company's template type, either Type A or Type B
        /// Default Combined
        /// </summary>
        public TemplateTypeEnum TemplateType { get; set; }


        /// <summary>
        /// Apply grouping for comparative group by Industry group or by Peer Group.
        /// Default Peer group
        /// </summary>
        public ComparativeGroupEnum GroupBy { get; set; }

        /// <summary>
        ///  Response include in response aggregates like min, max, avg for themes and clusters.
        /// Default value: FALSE
        /// </summary>
        public bool IncludeAggregatedScores { get; set; }

        /// <summary>
        /// Response includes weighted scores for all indicators.
        /// Default value: FALSE
        /// </summary>
        public bool IncludeIndWeightedScores { get; set; }

        /// <summary>
        ///  Response includes weights from the selected matrix.
        ///  Default value: FALSE
        /// </summary>
        public bool IncludeWeights { get; set; }

        /// <summary>
        /// Response incudes ratings(raw scores) for all indicators
        /// Default value : TRUE
        /// </summary>
        public bool IncludeRatings { get; set; }


        /// <summary>
        /// Response incudes weights sum by theme and cluster
        /// Default value: FALSE
        /// </summary>
        public bool IncludeAggregatedWeights { get; set; }

        /// <summary>
        /// Response includes information about Top performers 5 for every theme or cluster for requested company in her comparative group.
        /// ATTENTION: Respose will be very verbose, as every company will have 5(top performers)*8(themes and clusters) companies listed.
        /// Default value: FALSE
        /// </summary>
        public bool IncludeTopPerformersInfo { get; set; }

        /// <summary>
        /// Response includes information about other companies in comparative group for the requested companies.
        /// Used in usecases where I should compute both top 5 performers and industry peers by market capitalization.
        /// Default value: FALSE
        /// </summary>
        public bool IncludeCompaniesInGroup { get; set; }



        /// <summary>
        /// Filter response by industry groups specified here.
        /// To be developed this feature.
        /// </summary>
        public List<string> IndustryGroups { get; set; }


        /// <summary>
        /// Filter response by peer groups specified here.
        /// To be developed this feature.
        /// </summary>
        public List<string> PeerGroups { get; set; }


        /// <summary>
        /// Filter by sedId. Support for multiset.
        /// </summary>
        public Guid? SetId { get; set; } //requested set


        /// <summary>
        /// Matrix Id used for computation. 
        /// Mandatory otherwise will get a 404 Response
        /// </summary>
        public Guid MatrixId { get; set; } // requested matrix


        /// <summary>
        /// Reference universe Id used for computation.
        /// Mandatory otherwise will get a 404 Response
        /// </summary>
        public Guid RefUnivId { get; set; } //requested ref univ


        public ESGRatingsOptions ToDomainModel()
        {
            ESGRatingsOptions dto = new ESGRatingsOptions();

            if (CompaniesIds != null)
                dto.CompaniesIds = new List<Guid>(CompaniesIds);

            dto.GroupBy = GroupBy;
            dto.MatrixId = MatrixId;
            dto.PeerGroups = PeerGroups;
            dto.IndustryGroups = IndustryGroups;
            dto.RefUnivId = RefUnivId;
            dto.TemplateType = TemplateType;
            dto.CompanyType = CompanyType;
            dto.SetId = SetId;

            dto.Include = 0;
            if (IncludeAggregatedScores) dto.Include |= ESGRatingsOptions.IncludeFlags.IncludeAggregatedScores;
            if (IncludeIndWeightedScores) dto.Include |= ESGRatingsOptions.IncludeFlags.IncludeIndWeightedScores;
            if (IncludeRatings) dto.Include |= ESGRatingsOptions.IncludeFlags.IncludeRatings;
            if (IncludeAggregatedWeights) dto.Include |= ESGRatingsOptions.IncludeFlags.IncludeAggregatesWeights;
            if (IncludeWeights) dto.Include |= ESGRatingsOptions.IncludeFlags.IncludeWeights;

            return dto;
        }

        public static ESGRatingsOptionsDto ToDto(ESGRatingsOptions options)
        {
            ESGRatingsOptionsDto dto = new ESGRatingsOptionsDto();

            if (options.CompaniesIds != null)
                dto.CompaniesIds = new List<Guid>(options.CompaniesIds);

            dto.GroupBy = options.GroupBy;
            dto.MatrixId = options.MatrixId;
            dto.PeerGroups = options.PeerGroups;
            dto.IndustryGroups = options.IndustryGroups;
            dto.RefUnivId = options.RefUnivId;

            dto.IncludeAggregatedScores = (options.Include & ESGRatingsOptions.IncludeFlags.IncludeAggregatedScores) != 0;
            dto.IncludeIndWeightedScores = (options.Include & ESGRatingsOptions.IncludeFlags.IncludeIndWeightedScores) != 0;
            dto.IncludeRatings = (options.Include & ESGRatingsOptions.IncludeFlags.IncludeRatings) != 0;
            dto.IncludeWeights = (options.Include & ESGRatingsOptions.IncludeFlags.IncludeWeights) != 0;
            dto.IncludeAggregatedWeights = (options.Include & ESGRatingsOptions.IncludeFlags.IncludeAggregatesWeights) != 0;
            return dto;
        }
    }


}